<template>
  <el-dialog
    :title="_transitionLanguages('button', 'permissionSetting')"
    v-model="dialogVisible"
    width="800px"
    top="10vh"
    :destroy-on-close="true"
    draggable
    :close-on-click-modal="false"
    @close="dialogVisible = false"
  >
    <div class="op-perm-box">
      <div v-loading="treeData.left.loading">
        <div class="title">待配置权限</div>

        <div class="tree">
          <div class="btn">
            <el-button type="primary" plain @click="operationPermission('add')">
              <SvgIcon name="el-Plus" class="mr5" />
              批量新增
            </el-button>
          </div>
          <el-tree-v2
            :ref="ref => (treeData.left.ref = ref)"
            :data="treeData.left.data"
            :props="treeProps"
            check-on-click-node
            :default-expanded-keys="treeData.left.defaultExpandedKeys"
            :height="400"
            show-checkbox
          >
            <template #default="{ node, data }">
              <span>{{ node.label }} ( {{ data.permName }} )</span>
            </template>
          </el-tree-v2>
        </div>
      </div>

      <div v-loading="treeData.right.loading">
        <div class="title">已配置权限</div>
        <div class="tree">
          <div class="btn">
            <el-button type="danger" plain @click="operationPermission('delete')">
              <SvgIcon name="del" class="mr5" />
              批量删除
            </el-button>
          </div>
          <el-tree-v2
            :ref="ref => (treeData.right.ref = ref)"
            :data="treeData.right.data"
            check-on-click-node
            :height="400"
            :default-expanded-keys="treeData.right.defaultExpandedKeys"
            :props="treeProps"
            show-checkbox
          >
            <template #default="{ node, data }">
              <span>{{ node.label }} ( {{ data.permName }} )</span>
            </template>
          </el-tree-v2>
        </div>
      </div>
    </div>

    <template #footer> </template>
  </el-dialog>
</template>
<script setup lang="ts">
import { ProTableInstance } from '@/components/ProTable/interface';
const treeProps = {
  value: 'id',
  label: 'description',
  children: 'children'
};

interface OpPermProps {
  tableRef: ProTableInstance;
}

let treeData = reactive({
  left: {
    loading: false,
    ref: null,
    data: [],
    defaultExpandedKeys: []
  },
  right: {
    loading: false,
    ref: null,
    data: [],
    defaultExpandedKeys: []
  }
});

// 接受父组件参数，配置默认值
const props = withDefaults(defineProps<OpPermProps>(), {
  tableRef: null
});
let dialogVisible = ref(false);

function open() {
  dialogVisible.value = true;
  nextTick(() => {
    init(true);
  });
}

// 语言转换
const _transitionLanguages = (v: string, l: string): string => {
  return transitionLanguages(v, l);
};

// 获取菜单列表
const init = (flag?: boolean) => {
  treeData.left.loading = true;
  treeData.right.loading = true;

  const params = {
    roleId: props.tableRef.clickRow.id
  };
  permissionFindByRoleId(params).then(data => {
    Object.assign(treeData.right, {
      data,
      loading: false
    });
    let keys = getExpandedKeys(data);
    treeData.right.ref.setCheckedKeys([]);
    if (flag) {
      treeData.right.ref.setExpandedKeys(keys);
    }
  });

  permissionFindByNoRoleId(params).then(data => {
    Object.assign(treeData.left, {
      data,
      loading: false
    });
    let keys = getExpandedKeys(data);
    if (flag) {
      treeData.left.ref.setExpandedKeys(keys);
    }
    treeData.left.ref.setCheckedKeys([]);
  });
};

const operationPermission = (type: 'add' | 'delete') => {
  // treeData.loading = true;
  const flag = type === 'add';
  const api = flag ? roleSavePremByRoleId : roleDelPremByRoleId;

  let checkedNodes = flag ? treeData.left.ref.getCheckedNodes() : treeData.right.ref.getCheckedNodes();
  let halfCheckedNodes = flag ? treeData.left.ref.getHalfCheckedNodes() : treeData.right.ref.getHalfCheckedNodes();
  let detailIds = [...checkedNodes, ...halfCheckedNodes];

  console.log(halfCheckedNodes, 'detailIds', checkedNodes);

  if (detailIds.length) {
    detailIds = arrLiftField(detailIds, 'id');
    if (type === 'delete') {
      // 删除是，如果没有把对应子集全部删除那么父级节点不能删除
      detailIds = getAncestorLabels(treeData.right.data, arrLiftField(checkedNodes, 'id'));
    }
  }

  console.log(detailIds, 'detailIds');

  treeData.left.loading = true;
  treeData.right.loading = true;

  api({ id: props.tableRef.clickRow.id, detailIds })
    .then(() => {
      elMessage();
      init();
    })
    .catch(() => {
      treeData.left.loading = false;
      treeData.right.loading = false;
    });
};

/**
 * 获取菜单中最后一级children
 */
function getAncestorLabels(tree, ids) {
  const result = new Set();

  function dfs(node) {
    // 叶子节点
    if (!node.children || node.children.length === 0) {
      if (ids.includes(node.id)) {
        result.add(node.id);
        return { selected: true, allChildrenSelected: true };
      }
      return { selected: false, allChildrenSelected: false };
    }

    let allChildrenSelected = true;

    for (const child of node.children) {
      const childResult = dfs(child);
      if (!childResult.allChildrenSelected) {
        allChildrenSelected = false;
      }
    }

    // 如果所有子节点都满足条件（即全被选中）
    if (allChildrenSelected) {
      result.add(node.id);
      return { selected: true, allChildrenSelected: true };
    }

    return { selected: false, allChildrenSelected: false };
  }

  for (const root of tree) {
    dfs(root);
  }

  return Array.from(result);
}

/**获取需要展开节点的id */
const getExpandedKeys = data => {
  const result = [];
  for (let node of data) {
    result.push(node.id);
  }
  return result;
};

defineExpose({
  open
});
</script>

<style lang="scss" scoped src="./index.scss"></style>
